home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Clip.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  8KB  |  447 lines

  1. /*
  2. **    Clip.c
  3. **
  4. **    Clipboard support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. STATIC struct IFFHandle    *ClipHandle;
  17. STATIC STRPTR ClipBuffer,ClipIndex;
  18. STATIC LONG ClipSize,ClipLength;
  19.  
  20.     /* CloseClip():
  21.      *
  22.      *    Close clipboard handle, stop reading.
  23.      */
  24.  
  25. VOID
  26. CloseClip()
  27. {
  28.     CloseIFFClip(ClipHandle);
  29.     ClipHandle = NULL;
  30.  
  31.     FreeVecPooled(ClipBuffer);
  32.     ClipBuffer = NULL;
  33. }
  34.  
  35.     /* GetClip(STRPTR Buffer,LONG Len):
  36.      *
  37.      *    Read text data from clipboard and put it into the supplied buffer.
  38.      */
  39.  
  40. LONG
  41. GetClip(STRPTR Buffer,LONG Len)
  42. {
  43.     LONG BytesPut = 0;
  44.     LONG c;
  45.  
  46.         /* Is the read buffer already exhausted? */
  47.  
  48.     if(!ClipLength)
  49.     {
  50.             /* Is there still any data to read? */
  51.  
  52.         if(ClipSize)
  53.         {
  54.             LONG Size = MIN(ClipSize,1024);
  55.  
  56.                 /* Try to read the data and return failure if necessary. */
  57.  
  58.             if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  59.                 return(-1);
  60.             else
  61.             {
  62.                 ClipSize    -= Size;
  63.                 ClipLength     = Size;
  64.                 ClipIndex     = ClipBuffer;
  65.             }
  66.         }
  67.         else
  68.         {
  69.                 /* We just parsed a single chunk, now go on and
  70.                  * look for another one.
  71.                  */
  72.  
  73.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  74.             {
  75.                 struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  76.  
  77.                 if(ContextNode->cn_Type == ID_FTXT)
  78.                 {
  79.                     LONG Size;
  80.  
  81.                     ClipSize    = ContextNode->cn_Size;
  82.                     Size        = MIN(ClipSize,1024);
  83.  
  84.                     if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  85.                         return(-1);
  86.                     else
  87.                     {
  88.                         ClipSize    -= Size;
  89.                         ClipLength     = Size;
  90.                         ClipIndex     = ClipBuffer;
  91.                     }
  92.                 }
  93.                 else
  94.                     return(-1);
  95.             }
  96.             else
  97.                 return(-1);
  98.         }
  99.     }
  100.  
  101.     while(ClipLength && BytesPut < Len)
  102.     {
  103.         ClipLength--;
  104.  
  105.         switch(c = *ClipIndex++)
  106.         {
  107.             case '\r':
  108.  
  109.                 break;
  110.  
  111.             default:
  112.  
  113.                 if(IsPrintable[c])
  114.                 {
  115.                     *Buffer++ = c;
  116.                     BytesPut++;
  117.                 }
  118.  
  119.                 break;
  120.         }
  121.     }
  122.  
  123.     return(BytesPut);
  124. }
  125.  
  126.     /* OpenClip():
  127.      *
  128.      *    Open the clipboard for sequential reading.
  129.      */
  130.  
  131. LONG
  132. OpenClip(LONG Unit)
  133. {
  134.     LONG Error;
  135.  
  136.     CloseClip();
  137.  
  138.     if(ClipBuffer = (STRPTR)AllocVecPooled(1024,MEMF_ANY))
  139.     {
  140.         if(ClipHandle = OpenIFFClip(Unit,MODE_OLDFILE))
  141.         {
  142.             if(!(Error = StopChunk(ClipHandle,ID_FTXT,ID_CHRS)))
  143.             {
  144.                 if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  145.                 {
  146.                     struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  147.  
  148.                     if(ContextNode->cn_Type == ID_FTXT)
  149.                     {
  150.                         ClipSize    = ContextNode->cn_Size;
  151.                         ClipLength    = 0;
  152.  
  153.                         return(0);
  154.                     }
  155.                     else
  156.                         Error = ERROR_OBJECT_WRONG_TYPE;
  157.                 }
  158.                 else
  159.                     Error = ERROR_OBJECT_NOT_FOUND;
  160.             }
  161.         }
  162.         else
  163.             Error = IoErr();
  164.     }
  165.     else
  166.         Error = ERROR_NO_FREE_STORE;
  167.  
  168.     CloseClip();
  169.  
  170.     return(Error);
  171. }
  172.  
  173.     /* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
  174.      *
  175.      *    Merge text contents of the clipboard into a single string.
  176.      */
  177.  
  178. BOOL
  179. GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
  180. {
  181.     struct IFFHandle *Handle;
  182.     LONG Bytes;
  183.     APTR Store;
  184.  
  185.     Store = NULL;
  186.     Bytes = 0;
  187.  
  188.     if(Handle = OpenIFFClip(Unit,MODE_OLDFILE))
  189.     {
  190.         if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  191.         {
  192.             struct ContextNode *Node;
  193.  
  194.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  195.             {
  196.                 Node = CurrentChunk(Handle);
  197.  
  198.                 if(Node->cn_Type == ID_FTXT)
  199.                     Bytes += Node->cn_Size;
  200.             }
  201.         }
  202.  
  203.         CloseIFFClip(Handle);
  204.     }
  205.  
  206.     if(Bytes > 0)
  207.     {
  208.         if(Handle = OpenIFFClip(Unit,MODE_OLDFILE))
  209.         {
  210.             if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  211.             {
  212.                 if(Store = AllocVecPooled(Bytes,MEMF_ANY))
  213.                 {
  214.                     struct ContextNode *Node;
  215.                     LONG BytesRead;
  216.                     STRPTR Index;
  217.  
  218.                     Index        = Store;
  219.                     BytesRead    = 0;
  220.  
  221.                     while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
  222.                     {
  223.                         Node = CurrentChunk(Handle);
  224.  
  225.                         if(Node->cn_Type == ID_FTXT)
  226.                         {
  227.                             LONG Count = Node->cn_Size;
  228.  
  229.                             if(BytesRead + Count > Bytes)
  230.                                 Count = Bytes - BytesRead;
  231.  
  232.                             if(Count > 0)
  233.                             {
  234.                                 if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
  235.                                 {
  236.                                     Index        += Count;
  237.                                     BytesRead    += Count;
  238.                                 }
  239.                             }
  240.                         }
  241.                     }
  242.  
  243.                     Bytes = BytesRead;
  244.                 }
  245.             }
  246.  
  247.             CloseIFFClip(Handle);
  248.         }
  249.     }
  250.  
  251.     if(Store && !Bytes)
  252.     {
  253.         FreeVecPooled(Store);
  254.  
  255.         Store = NULL;
  256.     }
  257.  
  258.     *Buffer    = Store;
  259.     *Size    = Bytes;
  260.  
  261.     return((BOOL)(Store != NULL));
  262. }
  263.  
  264.     /* AddClip(STRPTR Buffer,LONG Size):
  265.      *
  266.      *    Merge previous clipboard contents with new text,
  267.      *    then store the new string in the clipboard.
  268.      */
  269.  
  270. BOOL
  271. AddClip(STRPTR Buffer,LONG Size)
  272. {
  273.     LONG Bytes;
  274.     APTR Store;
  275.  
  276.     if(GetClipContents(Config->ClipConfig->ClipboardUnit,&Store,&Bytes))
  277.     {
  278.         struct IFFHandle *Handle;
  279.         LONG Error;
  280.  
  281.         if(Handle = OpenIFFClip(Config->ClipConfig->ClipboardUnit,MODE_NEWFILE))
  282.         {
  283.             if(!(Error = PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN)))
  284.             {
  285.                 if(!(Error = PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN)))
  286.                 {
  287.                     if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
  288.                     {
  289.                         if(WriteChunkBytes(Handle,Buffer,Size) != Size)
  290.                             Error = IoErr();
  291.                     }
  292.                     else
  293.                         Error = IoErr();
  294.  
  295.                     if(!Error)
  296.                         Error = PopChunk(Handle);
  297.                 }
  298.  
  299.                 if(!Error)
  300.                     Error = PopChunk(Handle);
  301.             }
  302.  
  303.             CloseIFFClip(Handle);
  304.         }
  305.         else
  306.             Error = IoErr();
  307.  
  308.         FreeVecPooled(Store);
  309.  
  310.         if(Error)
  311.         {
  312.             SetIoErr(Error);
  313.  
  314.             return(FALSE);
  315.         }
  316.         else
  317.             return(TRUE);
  318.     }
  319.     else
  320.         return(SaveClip(Buffer,Size));
  321. }
  322.  
  323.     /* SaveClip(STRPTR Buffer,LONG Size):
  324.      *
  325.      *    Send a given text buffer to the clipboard.
  326.      */
  327.  
  328. BOOL
  329. SaveClip(STRPTR Buffer,LONG Size)
  330. {
  331.     LONG Error;
  332.  
  333.     if(Size > 0)
  334.     {
  335.         struct IFFHandle *Handle;
  336.  
  337.         if(Handle = OpenIFFClip(Config->ClipConfig->ClipboardUnit,MODE_NEWFILE))
  338.         {
  339.             if(!(Error = PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN)))
  340.             {
  341.                 if(!(Error = PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN)))
  342.                 {
  343.                     if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  344.                         Error = PopChunk(Handle);
  345.                     else
  346.                         Error = IoErr();
  347.                 }
  348.             }
  349.  
  350.             if(!Error)
  351.                 Error = PopChunk(Handle);
  352.  
  353.             CloseIFFClip(Handle);
  354.         }
  355.         else
  356.             Error = IoErr();
  357.     }
  358.     else
  359.         Error = 0;
  360.  
  361.     if(Error)
  362.     {
  363.         SetIoErr(Error);
  364.  
  365.         return(FALSE);
  366.     }
  367.     else
  368.         return(TRUE);
  369. }
  370.  
  371.     /* LoadClip(STRPTR Buffer,LONG Size):
  372.      *
  373.      *    Put the contents of the clipboard into a given
  374.      *    buffer. Note that only the first FTXT chunk will
  375.      *    be read. Since this code will only be called by
  376.      *    the clipboard server process which serves the
  377.      *    string gadget editing hook, this will hopefully
  378.      *    not be fatal. If you want more data to be read,
  379.      *    including multiple FTXT chunks, use the OpenClip(),
  380.      *    GetClip(), CloseClip() combo above.
  381.      */
  382.  
  383. LONG
  384. LoadClip(STRPTR Buffer,LONG Size)
  385. {
  386.     struct IFFHandle *Handle;
  387.     LONG Bytes;
  388.  
  389.     Bytes = 0;
  390.  
  391.     if(Handle = OpenIFFClip(Config->ClipConfig->ClipboardUnit,MODE_OLDFILE))
  392.     {
  393.         if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  394.         {
  395.             if(!ParseIFF(Handle,IFFPARSE_SCAN))
  396.             {
  397.                 struct ContextNode *ContextNode = CurrentChunk(Handle);
  398.  
  399.                 if(ContextNode->cn_Type == ID_FTXT)
  400.                 {
  401.                     if(Size > ContextNode->cn_Size)
  402.                         Size = ContextNode->cn_Size;
  403.  
  404.                     if(ReadChunkRecords(Handle,Buffer,Size,1))
  405.                         Bytes = Size;
  406.                 }
  407.             }
  408.         }
  409.  
  410.         CloseIFFClip(Handle);
  411.     }
  412.  
  413.     return(Bytes);
  414. }
  415.  
  416. BOOL
  417. WriteTranslatedToClip(struct IFFHandle *Handle,STRPTR Buffer,LONG Length)
  418. {
  419.     UBYTE LocalBuffer[256];
  420.     LONG DestLen,i;
  421.     LONG c;
  422.  
  423.     for(i = DestLen = 0 ; i < Length ; i++)
  424.     {
  425.         if(!(c = ISOConversion[Buffer[i]]))
  426.             c = ' ';
  427.  
  428.         LocalBuffer[DestLen++] = c;
  429.  
  430.         if(DestLen == sizeof(LocalBuffer))
  431.         {
  432.             if(WriteChunkBytes(Handle,LocalBuffer,DestLen) != DestLen)
  433.                 return(FALSE);
  434.  
  435.             DestLen = 0;
  436.         }
  437.     }
  438.  
  439.     if(DestLen > 0)
  440.     {
  441.         if(WriteChunkBytes(Handle,LocalBuffer,DestLen) != DestLen)
  442.             return(FALSE);
  443.     }
  444.  
  445.     return(TRUE);
  446. }
  447.